using System;
using System.Collections.Generic;
using System.Xml;
using System.Diagnostics;
using System.Threading;

namespace XML_Engine
{
    public class XML_Settings
    {
        private Dictionary<string, string> _cache;
        private XmlDocument _xml;
        private string _path;
        private Mutex _mut;

        public string this[string xpath]
        {
            get
            {
                if (this._cache.ContainsKey(xpath))
                {
                    this._retCache(xpath);
                    return this._cache[xpath];
                }
                else
                {
                    this._retXml(xpath);
                    try
                    {
                        string val = this._xml.SelectSingleNode(xpath).InnerText;
                        this._cache.Add(xpath, val);
                        return val;
                    }
                    catch(NullReferenceException)
                    {
                        return null;
                    }
                }
            }
            set
            {
                // INFO: Saved settings are always cached!
                this._mut.WaitOne();
                this._cache[xpath] = value;
                this._xml.SelectSingleNode(xpath).InnerText = value;
                this._mut.ReleaseMutex();
            }
        }
        public void Load(string xmlpath)
        {
            this._path = xmlpath;
            this._infoLoad(this._path);
            this._xml.Load(this._path);
        }
        public void Save()
        {
            this._infoSave();
            this._xml.Save(this._path);
        }
        ~XML_Settings()
        {
            this._infoDestroy();
            this.Save();
        }

        #region Debug stuff

        [Conditional("DEBUG")]
        private void _infoDestroy()
        {
            Trace.TraceInformation("Destroying " + typeof(XML_Settings));
        }
        [Conditional("DEBUG")]
        private void _infoCreate()
        {
            Trace.TraceInformation("Creating " + typeof(XML_Settings));
        }
        [Conditional("DEBUG")]
        private void _infoLoad(string file)
        {
            Trace.TraceInformation("Loading: " + file);
        }
        [Conditional("DEBUG")]
        private void _infoSave()
        {
            Trace.TraceInformation("Saving: " + this._path);
        }
        [Conditional("DEBUG")]
        private void _retXml(string key)
        {
            Trace.TraceInformation("Returned value of {0} from XML", key);
        }
        [Conditional("DEBUG")]
        private void _retCache(string key)
        {
            Trace.TraceInformation("Returned value of {0} from internal cache", key);
        }

        #endregion
        #region Singleton stuff

        private XML_Settings()
        {
            this._infoCreate();
            this._cache = new Dictionary<string, string>();
            this._xml = new XmlDocument();
            this._mut = new Mutex();
        }

        public static XML_Settings Instance
        {
            get
            {
                return Nested.instance;
            }
        }

        class Nested
        {
            internal static readonly XML_Settings instance = new XML_Settings();

            static Nested()
            {
            }
        }

        #endregion
    }
}
